<template>
  <div
    :class="[sizeClass]"
  >
    <VueTreeselect
      v-bind="$attrs"
      v-on="$listeners"
      v-model="syncValue"
      :options="options"
      :placeholder="placeholder"
      :normalizer="normalizerCom"
      :noChildrenText="noChildrenText"
      :noOptionsText="noOptionsText"
      :noResultsText="noResultsText"
      :valueConsistsOf="valueConsistsOf"
      :appendToBody="appendToBody"
      :alwaysOpen="alwaysOpen"
      :defaultExpandLevel="defaultExpandLevel"
      :maxHeight="maxHeight"
      :zIndex="zIndex"
      @input="inputCom"
      @open="openCom"
    >
      <template #after-list v-if="$slots.afterList">
        <slot name="after-list"></slot>
      </template>
      <template #before-list v-if="$slots.beforeList">
        <slot name="before-list"></slot>
      </template>
      <template #option-label="params" v-if="$slots.optionLabel">
        <slot name="option-label" v-bind="params"></slot>
      </template>
      <template #value-label="params" v-if="$slots.valueLabel">
        <slot name="value-label" v-bind="params"></slot>
      </template>
    </VueTreeselect>
  </div>
</template>

<script lang="ts">
/**
 * 父子不关联：:flat="true" 解释为扁平化
 */
import VueTreeselect from '@riophae/vue-treeselect'
// 导入treeSelect样式
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import {PropType} from "vue/types/options";
import typeOfUtils from "../../utils/type-of-utils";
import PopupManager from "element-ui/lib/utils/popup/popup-manager";
import {Props, PropsDefault} from './Type'

export default {
  name: "TreeSelect",
  components: {
    VueTreeselect
  },
  props: {
    value: {
      type: [String, Number, Array],
      default: () => undefined
    },
    options: {
      type: Array,
      default: () => []
    },
    props: {
      type: Object as PropType<Props>,
      default: (): Props => PropsDefault
    },
    normalizer: Function,
    loadOptions: Function,
    placeholder: {
      type: String,
      default: '请选择'
    },
    noChildrenText: {
      type: String,
      default: '暂无子节点'
    },
    noOptionsText: {
      type: String,
      default: '没有可用选项'
    },
    noResultsText: {
      type: String,
      default: '未匹配到结果'
    },
    valueConsistsOf: {
      type: String as PropType<'ALL'>,
      default: 'ALL'
    },
    appendToBody: {
      type: Boolean,
      default: true
    },
    alwaysOpen: { // 下拉框总是展开
      type: Boolean,
      default: false
    },
    defaultExpandLevel: { // 默认展开的等级
      type: Number,
      default: 0, // Infinity 全展开
    },
    maxHeight: { // 下拉框的最大高度
      type: Number,
      default: 300,
    },
    size: {
      type: String,
    }
  },
  computed: {
    syncValue: {
      set(val) {
        this.$emit('input', val)
      },
      get() {
        return this.value
      }
    },
    sizeClass() {
      if(this.size === 'mini') {
        return 'vueTreeSelectMini'
      }
      return 'vueTreeSelectSmall'
    }
  },
  data() {
    return {
      zIndex: undefined
    }
  },
  methods: {
    normalizerCom(node) {
      if (this.normalizer) {
        return this.normalizer(node)
      }
      const props = {
        ...PropsDefault,
        ...this.props
      }
      if (!this.loadOptions) {
        if (typeOfUtils.isEmpty(node[props.children])) {
          return {
            id: node[props.value],
            label: node[props.label],
            children: undefined
          }
        }
      }
      return {
        id: node[props.value],
        label: node[props.label],
        children: node[props.children],
      }
    },
    inputCom(val) {
      this.$emit('input', val)
    },
    openCom(e) {
      if (this.appendToBody) {
        this.zIndex = PopupManager.nextZIndex()
      }
      this.$emit('open', e)
    }
  }
}
</script>

<style lang="scss">
.vue-treeselect__portal-target{
  &.vue-treeselect{
    &.vue-treeselect--searchable{
      &.vue-treeselect--open-below{
        &.vue-treeselect--append-to-body{
          min-width: 500px;
        }
      }
      &.vue-treeselect--open-above{
        @extend .vue-treeselect--open-below;
      }
    }
  }
}
.TreeSelectBase{
  display: flex;
  align-items: center;
}

/* small */
$SmallHeight: 32px;
$SmallFontSize: 13px;
.vueTreeSelectSmall{
  line-height: 42px;
  height: 42px;
  @extend .TreeSelectBase;
}
.vueTreeSelectSmall .vue-treeselect__control {
  height: $SmallHeight;
  line-height: $SmallHeight;
}
.vueTreeSelectSmall .vue-treeselect__control .vue-treeselect__value-container {
  height: $SmallHeight;
  line-height: $SmallHeight;
}
.vueTreeSelectSmall
.vue-treeselect__control
.vue-treeselect__value-container
.vue-treeselect__placeholder {
  font-size: $SmallFontSize;
}
.vueTreeSelectSmall
.vue-treeselect__control
.vue-treeselect__value-container
.vue-treeselect__single-value {
  line-height: $SmallHeight;
  font-size: $SmallFontSize;
}

/* mini */
$MiniHeight: 26px;
$MiniFontSize: 12px;
.vueTreeSelectMini{
  line-height: 42px;
  height: 42px;
  @extend .TreeSelectBase;
}
.vueTreeSelectMini .vue-treeselect__control {
  height: $MiniHeight;
  line-height: $MiniHeight;
}
.vueTreeSelectMini .vue-treeselect__control .vue-treeselect__value-container {
  height: $MiniHeight;
  line-height: $MiniHeight;
}
.vueTreeSelectMini
.vue-treeselect__control
.vue-treeselect__value-container
.vue-treeselect__placeholder {
  font-size: $MiniFontSize;
}
.vueTreeSelectMini
.vue-treeselect__control
.vue-treeselect__value-container
.vue-treeselect__single-value {
  line-height: $MiniHeight;
  font-size: $MiniFontSize;
}



//.vue-treeselect{
//  .vue-treeselect__control{
//    background-color: $--input-bg-color;
//    border: 1px solid $--popper-border-color;
//  }
//  .vue-treeselect__single-value{
//    color: $--input-font-color;
//  }
//}
//.vue-treeselect--open-below .vue-treeselect__menu{
//  background-color: $--popper-bg-color;
//  color: $--popper-font-color;
//  .vue-treeselect__option--highlight{ // 高亮
//    background-color: $--popper-bg-color-hover;
//    color: $--popper-font-color-hover;
//    .vue-treeselect__option-arrow-container{
//      svg{ // 箭头颜色
//        color: $--popper-font-color-hover;
//      }
//    }
//  }
//}
//.vue-treeselect--single{
//  .vue-treeselect__option--selected{
//    background-color: $--tree-select-bg-color-hover;
//    color: #409EFF;
//    &:hover{
//      background-color: $--popper-bg-color-hover;
//    }
//  }
//}
</style>
<style scoped lang="scss">
.vue-treeselect{
  border-radius: 4px;
}
</style>
